<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>pixi键盘掉落</title>
    <style>
    body,p{
		margin: 0;
		padding: 0;
	}
    canvas{
        margin: 0;
        padding: 0;
        display: block; /*  ˉ\_(ツ)_/ˉ  */
        touch-action: none; 
    }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
    <script>
        //创建应用
        const app = new PIXI.Application({
            transparent: true,
            width: window.innerWidth,
            height: window.innerHeight,
        });
        document.body.appendChild(app.view);
        console.log('app',app);

        window.app = app;

        let scoreNum=0; //分数
        let target=null; //拖动元素
        let textSprite=null; //文字精灵，用户显示分数
        let containerSprite=null; //掉落物精灵的集合

        //加载
        app.loader
        .add('target', 'https://img.alicdn.com/imgextra/i3/826052692/O1CN01911GsZ1VkyrtJEFvO_!!826052692.png')
        .add("hongbao",'https://img.alicdn.com/imgextra/i3/826052692/O1CN01QyxlOF1VkyrnE5Rc2_!!826052692.png')
        .add("bg",'https://img.alicdn.com/imgextra/i4/826052692/O1CN01Ho8jJp1Vkyrj0QClq_!!826052692.png',function () {
            console.log("progress bg");
        })
        .on("progress", (aa)=>{
            console.log("progress",aa);
        })
        .load((loader, resources) => {
            for(let p in resources){
                if(resources[p].error){
                    console.log(resources[p]);
                }
            }
           
            //从纹理中创建背景元素
            const bg = new PIXI.Sprite(resources.bg.texture);
            bg.x =0;
            bg.y =0;
            bg.width = window.innerWidth;
            bg.height = window.innerHeight;
            app.stage.addChild(bg);//放入舞台
            
            //从纹理中创建拖动元素
            target = new PIXI.Sprite(resources.target.texture);
            target.width = window.innerWidth*0.4;
            target.height = window.innerWidth*0.3;
            target.x = (app.renderer.width /4)-(target.width/4);
            target.y = app.renderer.height / 6*5;
            target.anchor.x = 0.5;
            target.anchor.y = 0.5;
            app.stage.addChild(target);//放入舞台


            textSprite = new PIXI.Text("掉落开始!",new PIXI.TextStyle({
                fontFamily: "Arial",
                fontSize: 36,
                fill: "white",
                stroke: '#ff3300',
                strokeThickness: 4,
                dropShadow: true,
                dropShadowColor: "#000000",
                dropShadowBlur: 4,
                dropShadowAngle: Math.PI / 6,
                dropShadowDistance: 6,
            }));
            textSprite.anchor.x = 0.5;
            textSprite.anchor.y = 0.5;
            textSprite.position.set(app.renderer.view.width / 2, app.renderer.view.height / 12);
            app.stage.addChild(textSprite);

            //创建红包的容器，并放入舞台
            containerSprite = new PIXI.Container();
            app.stage.addChild(containerSprite);

            
            let i=3;
            setInterval(() => {
                i++
                if(containerSprite.children.length>2) return;
                let newSprite = new PIXI.Sprite(resources['hongbao'].texture);
                newSprite.width = window.innerWidth*0.15;
                newSprite.height = window.innerWidth*0.2;
                newSprite.anchor.x = 0.5;
                newSprite.anchor.y = 0.5;
                newSprite.position.set(app.renderer.width /4* Math.ceil(Math.random()*4)-newSprite.width+3,10)
                containerSprite.addChild(newSprite);
            }, 500);

            //循环，红包合集中的红包
            app.ticker.add(delta =>{
                let array = containerSprite.children
                for (let index = 0; index < array.length; index++) {
                    const element = array[index];
                    element.y +=   delta+3+ Math.ceil(scoreNum/10) 
                }
                checkHit();
            });

            tuodong();
            jianpan();
            
        });

        //碰撞检测
        function checkHit(){
            let array = containerSprite.children
            // console.log(array);
            for (let index = 0; index < array.length; index++) {
                const element = array[index];
                    if (hitTestRectangle(target, element)) {
                        console.log('hit')
                        scoreNum+=2;
                        textSprite.text=scoreNum;
                        containerSprite.removeChild(element);
                    
                    } else if(element.y>app.renderer.height){
                        scoreNum+=-3;
                        textSprite.text=scoreNum;
                        containerSprite.removeChild(element);
                    }
            }
        }

        function hitTestRectangle(r1, r2) {

            //Define the variables we'll need to calculate
            let hit, combinedHalfWidths, combinedHalfHeights, vx, vy;
        
            //hit will determine whether there's a collision
            hit = false;
        
            //Find the center points of each sprite
            r1.centerX = r1.x + r1.width / 2;
            r1.centerY = r1.y + r1.height / 2;
            r2.centerX = r2.x + r2.width / 2;
            r2.centerY = r2.y + r2.height / 2;
        
            //Find the half-widths and half-heights of each sprite
            r1.halfWidth = r1.width / 2;
            r1.halfHeight = r1.height / 2;
            r2.halfWidth = r2.width / 2;
            r2.halfHeight = r2.height / 2;
        
            //Calculate the distance vector between the sprites
            vx = r1.centerX - r2.centerX;
            vy = r1.centerY - r2.centerY;
        
            //Figure out the combined half-widths and half-heights
            combinedHalfWidths = r1.halfWidth + r2.halfWidth;
            combinedHalfHeights = r1.halfHeight + r2.halfHeight;
        
            //Check for a collision on the x axis
            if (Math.abs(vx) < combinedHalfWidths) {
        
            //A collision might be occuring. Check for a collision on the y axis
            if (Math.abs(vy) < combinedHalfHeights) {
        
                //There's definitely a collision happening
                hit = true;
            } else {
        
                //There's no collision on the y axis
                hit = false;
            }
            } else {
        
            //There's no collision on the x axis
            hit = false;
            }
        
            //`hit` will be either `true` or `false`
            return hit;
        };


        //绑定拖动事件 
        function tuodong(){
            var startX = 0; // 获取手指初始坐标
			var startY = 0;
			var x = 0; // 获得盒子原来的位置
			var y = 0;
            window.addEventListener('touchstart', function(e) {
                console.log("touchstart",e);
				// 获取手指初始坐标
				startX = e.targetTouches[0].pageX;
				startY = e.targetTouches[0].pageY;
				x = target.x;
				y = target.y;
			});
			// 手指离开
			window.addEventListener('touchend', function(e) {
				
			});
		
			// 手指按住移动
			window.addEventListener('touchmove', function(e) {
				// 计算手指的移动距离：手指移动之后的坐标减去手指初始的坐标
				var moveX = e.targetTouches[0].pageX - startX;
				var moveY = 0// e.targetTouches[0].pageY - startY;
				// 移动盒子 盒子原来的位置 + 手指移动的距离
				target.x = x + moveX;
				target.y = y + moveY;
				e.preventDefault(); // 阻止屏幕滚动的默认行为
			});
        }
        

        //绑定键盘事件
        function jianpan(){
            let keyObject = keyboard(65);
            keyObject.press = () => {
                //console.log('65 press')
                const next= target.x-(app.renderer.width /4)
                target.x= next>0 ? next : target.x;
            };
            keyObject.release = () => {
                // console.log('65 release',target.x)
            };

            let keyObject2 = keyboard(68);
            keyObject2.press = () => {
                //console.log('68 press')
                const next= target.x+(app.renderer.width /4)
                target.x= next < window.innerWidth? next : target.x;
            };
            keyObject2.release = () => {
                // console.log('68 release',target.x)
            };
        }
        function keyboard(keyCode) {
            let key = {};
            key.code = keyCode;
            key.isDown = false;
            key.isUp = true;
            key.press = undefined;
            key.release = undefined;
            //The `downHandler`
            key.downHandler = event => {
                if (event.keyCode === key.code) {
                    if (key.isUp && key.press) key.press();
                    key.isDown = true;
                    key.isUp = false;
                }
                event.preventDefault();
            };
        
            //The `upHandler`
            key.upHandler = event => {
                if (event.keyCode === key.code) {
                    if (key.isDown && key.release) key.release();
                    key.isDown = false;
                    key.isUp = true;
                }
                event.preventDefault();
            };
        
            //Attach event listeners
            window.addEventListener(
                "keydown", key.downHandler.bind(key), false
            );
            window.addEventListener(
                "keyup", key.upHandler.bind(key), false
            );
            return key;
        }
    </script>
</body>
</html>

